package org.feng.entity;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.jboss.logging.Logger;

/**
 * 线程安全的实体类池,通过getEntityObject(Entity.class) 获取实体类, getListEntityObject(Class<?>
 * cl,int count) 获取实体类列表
 * 
 * @author FengWenXue
 *
 */
public class EntityPool {
	private static final Logger LOG = Logger.getLogger(EntityPool.class);
	// 实体池 线程,调用类名+行号,实体 实例
	private final static HashMap<Thread, HashMap<String, Object>> POOL = new HashMap<Thread, HashMap<String, Object>>();

	// 禁止用new方式建实体类
	public EntityPool() {// private
		// LOG.info("xinj新实体 ");
	}

	private static long CUR_TIME = System.currentTimeMillis();
	private static long JG_TIME = 10000;// 清理间隔时间10秒,超过10秒就清理

	/**
	 * 清理已经执行完毕的线程的实体池类
	 *
	 * @return
	 */
	@SuppressWarnings("unlikely-arg-type")
	public static boolean clear() {
		Iterator<Thread> it = POOL.keySet().iterator();
		while (it.hasNext()) {
				Thread run = it.next();
			if (run.getState() == Thread.State.TERMINATED) {
				// HashMap<String,Object> tValue=POOL.get(run);
				// tValue.clear();//清除池中已终止线程的所有实体类实例
				/*
				 * for (String varId : tValue.keySet()) { tValue.remove(varId);
				 * LOG.info("清除了线程实体池 |"+run.getId()+":"+ varId); }
				 */
				LOG.info("清除线程实体池 |" + run.getId() + ":" + run.getName());

				POOL.remove(run);
			} else {
				// LOG.info("无需要清除的线程实体");
			}
		}
		return true;
	}

	@SuppressWarnings("unchecked")
	public static Object getEntityObject(Class<?> cl) {
		if (System.currentTimeMillis() - CUR_TIME > JG_TIME) {
			clear();// 清理线程无效的缓存实体类
			CUR_TIME = System.currentTimeMillis();
		}

		Thread ct = Thread.currentThread();
		StackTraceElement em = ct.getStackTrace()[2];
		String varId = em.getClassName() + "|" + em.getLineNumber();/* +"|"+String.valueOf(em.hashCode()); */// 调用变量的位置作为实体名的ID
		// LOG.info("获取 |"+ct.getId()+":"+ varId);
		Object obj = null;

		if (!POOL.containsKey(ct)) {
			LOG.info("新建线程 |" + ct.getId());
			POOL.put(ct, new HashMap<String, Object>());
		}

		HashMap<String, Object> threadVer = POOL.get(ct);

		if (!threadVer.containsKey(varId)) {
			try {
				obj = cl.getDeclaredConstructor().newInstance();
			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
					| InvocationTargetException | NoSuchMethodException | SecurityException e) {
				e.printStackTrace();
				return null;
			}
			// obj=new EntityPool();
			threadVer.put(varId, obj);
			LOG.info("新建线程实体 |" + ct.getId() + ":" + varId);
		} else {
			obj = threadVer.get(varId);
		}
		// String methodName =
		// Thread.currentThread().getStackTrace()[2].getMethodName();//调用的方法名
		return obj;
	}

	@SuppressWarnings("unchecked")
	public static List<Object> getListEntityObject(Class<?> cl, int count) {
		if (System.currentTimeMillis() - CUR_TIME > JG_TIME) {
			clear();// 清理线程无效的缓存实体类
			CUR_TIME = System.currentTimeMillis();
		}

		Thread ct = Thread.currentThread();// 获取线程
		StackTraceElement em = ct.getStackTrace()[2];// 获取调用信息
		String varId = em.getClassName() + "|" + em.getLineNumber() + "|" + count;// 调用变量的位置作为实体名的ID
		// LOG.info("获取 |"+ct.getId()+":"+ varId);

		if (!POOL.containsKey(ct)) {
			LOG.info("没有缓存线程,建立线程 |" + ct.getId() + ":" + varId);
			POOL.put(ct, new HashMap<String, Object>());
		}

		HashMap<String, Object> threadVer = POOL.get(ct);

		List<Object> list = null;
		if (!threadVer.containsKey(varId)) {
			try {
				list = new ArrayList(count);
				Constructor<?> dec = cl.getDeclaredConstructor();
				Object obj = dec.newInstance();
				list.add(obj);
				LOG.info("列表 0|" + ct.getId() + ":" + varId);
				for (int index = 1; index < count; index++) {
					if (obj instanceof Cloneable) {
						// list.add(((Cloneable)obj).clone());
					} else {
						list.add(dec.newInstance());
						LOG.info("列表 " + index + "|" + ct.getId() + ":" + varId);

					}
					// list.add(obj.clone());
				}
			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
					| InvocationTargetException | NoSuchMethodException | SecurityException e) {
				e.printStackTrace();
				return null;
			}
			// obj=new EntityPool();
			threadVer.put(varId, list);
			LOG.info("没有缓存实体,建立新实体 |" + ct.getId() + ":" + varId);
		} else {
			list = (List) threadVer.get(varId);
		}
		// String methodName =
		// Thread.currentThread().getStackTrace()[2].getMethodName();//调用的方法名
		return list;
	}

}
